package xlog

import (
	"fmt"
	"runtime"
	"time"
)

// 统计函数耗时,用法：defer xlog.Ftime(time.Now())
//
// 因内部使用了反射机制，所以无法使用匿名函数进行多层函数名获取
// 所以此处暂时截至到此处，使用 defer xlog.Ftime(time.Now()) 的固定结构来统计时长
// 另，因内部使用了 go 队列的形式来进行入库，所以建议此函数使用在正常运行的结构中
// 可随时退出的命令行记录的话建议使用 defer xlog.RTime(time.Now()) 来记录日志
//
//	t	当前时间
func Ftime(t time.Time) {
	// 耗时时间
	pc, _, line, ok := runtime.Caller(1)
	go ftime(pc, line, ok, t)
}

// 统计函数耗时,用法：defer xlog.Rtime(time.Now())
//
// 因内部使用了反射机制，所以无法使用匿名函数进行多层函数名获取
// 所以此处暂时截至到此处，使用 defer xlog.Ftime(time.Now()) 的固定结构来统计时长
//
//	t	当前时间
func Rtime(t time.Time) {
	// 耗时时间
	pc, _, line, ok := runtime.Caller(1)
	ftime(pc, line, ok, t)
}

// 统计函数耗时的调用方法
// 单独拆分出来为了避免同一函数内层级太多的问题
//
//	pc	caller指针
//	lin	调用行
//	ok	是否调用成功
//	t	调用时间
func ftime(pc uintptr, lin int, ok bool, t time.Time) {
	func_name := ""
	if ok {
		fn := runtime.FuncForPC(pc)
		if fn != nil {
			func_name = fn.Name()
		}
	}
	if _default.Console {
		fmt.Printf("[FUN] %s:%d\t%dns\t%s", func_name, lin, time.Since(t).Nanoseconds(), time.Now().Format(time.DateTime))
	}
	if _default.DB == nil {
		return
	}
	inf := FuncLog{
		Func:      func_name,
		Line:      uint(lin),
		Runtime:   uint64(time.Since(t).Nanoseconds()),
		CreatedAt: time.Now().Format(time.DateTime),
	}
	_default.DB.Create(&inf)
	insertLog(nil, &inf, nil)
}
